const { Op } = require('sequelize');
const { Role, Permission, RolePermission, Admin } = require('../models');
const logger = require('../utils/logger');

class RolePermissionService {
  /**
   * 创建角色
   */
  async createRole(roleData, creatorId) {
    try {
      const { name, displayName, description, level, permissionIds } = roleData;

      // 检查角色名是否已存在
      const existingRole = await Role.findOne({
        where: { name }
      });

      if (existingRole) {
        throw new Error('角色名已存在');
      }

      // 创建角色
      const role = await Role.create({
        name,
        displayName,
        description,
        level: level || 0
      });

      // 分配权限
      if (permissionIds && permissionIds.length > 0) {
        const permissionAssignments = permissionIds.map(permissionId => ({
          roleId: role.id,
          permissionId,
          assignedBy: creatorId
        }));

        await RolePermission.bulkCreate(permissionAssignments);
      }

      return role;
    } catch (error) {
      logger.error('Create role failed:', error);
      throw error;
    }
  }

  /**
   * 获取角色列表
   */
  async getRoleList(options = {}) {
    try {
      const {
        page = 1,
        limit = 20,
        search,
        status,
        includePermissions = false
      } = options;

      const where = {};
      
      if (search) {
        where[Op.or] = [
          { name: { [Op.like]: `%${search}%` } },
          { displayName: { [Op.like]: `%${search}%` } }
        ];
      }

      if (status) {
        where.status = status;
      }

      const include = [];
      if (includePermissions) {
        include.push({
          model: Permission,
          as: 'permissions',
          attributes: ['id', 'name', 'displayName', 'resource', 'action']
        });
      }

      const { count, rows } = await Role.findAndCountAll({
        where,
        include,
        limit: parseInt(limit),
        offset: (parseInt(page) - 1) * parseInt(limit),
        order: [['level', 'DESC'], ['createdAt', 'DESC']]
      });

      return {
        roles: rows,
        pagination: {
          current: parseInt(page),
          total: Math.ceil(count / limit),
          pageSize: parseInt(limit),
          totalItems: count
        }
      };
    } catch (error) {
      logger.error('Get role list failed:', error);
      throw error;
    }
  }

  /**
   * 获取角色详情
   */
  async getRoleById(roleId) {
    try {
      const role = await Role.findByPk(roleId, {
        include: [{
          model: Permission,
          as: 'permissions'
        }]
      });

      if (!role) {
        throw new Error('角色不存在');
      }

      return role;
    } catch (error) {
      logger.error('Get role by id failed:', error);
      throw error;
    }
  }

  /**
   * 更新角色
   */
  async updateRole(roleId, updateData, updaterId) {
    try {
      const role = await Role.findByPk(roleId);
      
      if (!role) {
        throw new Error('角色不存在');
      }

      // 系统角色不能修改
      if (role.isSystem) {
        throw new Error('系统角色不能修改');
      }

      const { name, displayName, description, level, status, permissionIds } = updateData;

      // 检查角色名是否已被其他角色使用
      if (name && name !== role.name) {
        const existingRole = await Role.findOne({
          where: { 
            name,
            id: { [Op.ne]: roleId }
          }
        });

        if (existingRole) {
          throw new Error('角色名已存在');
        }
      }

      // 更新基本信息
      await role.update({
        name: name || role.name,
        displayName: displayName || role.displayName,
        description: description || role.description,
        level: level !== undefined ? level : role.level,
        status: status || role.status
      });

      // 更新权限分配
      if (permissionIds !== undefined) {
        // 删除现有权限
        await RolePermission.destroy({
          where: { roleId }
        });

        // 分配新权限
        if (permissionIds.length > 0) {
          const permissionAssignments = permissionIds.map(permissionId => ({
            roleId,
            permissionId,
            assignedBy: updaterId
          }));

          await RolePermission.bulkCreate(permissionAssignments);
        }
      }

      return role;
    } catch (error) {
      logger.error('Update role failed:', error);
      throw error;
    }
  }

  /**
   * 删除角色
   */
  async deleteRole(roleId) {
    try {
      const role = await Role.findByPk(roleId);
      
      if (!role) {
        throw new Error('角色不存在');
      }

      // 系统角色不能删除
      if (role.isSystem) {
        throw new Error('系统角色不能删除');
      }

      // 检查是否有管理员使用此角色
      const adminCount = await Admin.count({
        include: [{
          model: Role,
          as: 'roles',
          where: { id: roleId }
        }]
      });

      if (adminCount > 0) {
        throw new Error('该角色正在被使用，不能删除');
      }

      // 删除权限关联
      await RolePermission.destroy({
        where: { roleId }
      });

      // 删除角色
      await role.destroy();

      return true;
    } catch (error) {
      logger.error('Delete role failed:', error);
      throw error;
    }
  }

  /**
   * 创建权限
   */
  async createPermission(permissionData) {
    try {
      const { name, displayName, description, resource, action, category, parentId, level } = permissionData;

      // 检查权限名是否已存在
      const existingPermission = await Permission.findOne({
        where: { name }
      });

      if (existingPermission) {
        throw new Error('权限名已存在');
      }

      // 检查资源+操作组合是否已存在
      const existingResourceAction = await Permission.findOne({
        where: { resource, action }
      });

      if (existingResourceAction) {
        throw new Error('该资源的操作权限已存在');
      }

      const permission = await Permission.create({
        name,
        displayName,
        description,
        resource,
        action,
        category,
        parentId,
        level: level || 0
      });

      return permission;
    } catch (error) {
      logger.error('Create permission failed:', error);
      throw error;
    }
  }

  /**
   * 获取权限列表
   */
  async getPermissionList(options = {}) {
    try {
      const {
        page = 1,
        limit = 50,
        search,
        category,
        resource,
        status,
        tree = false
      } = options;

      const where = {};
      
      if (search) {
        where[Op.or] = [
          { name: { [Op.like]: `%${search}%` } },
          { displayName: { [Op.like]: `%${search}%` } },
          { resource: { [Op.like]: `%${search}%` } }
        ];
      }

      if (category) {
        where.category = category;
      }

      if (resource) {
        where.resource = resource;
      }

      if (status) {
        where.status = status;
      }

      if (tree) {
        // 返回树形结构
        const permissions = await Permission.findAll({
          where,
          order: [['level', 'ASC'], ['createdAt', 'ASC']]
        });

        return this.buildPermissionTree(permissions);
      } else {
        // 返回分页列表
        const { count, rows } = await Permission.findAndCountAll({
          where,
          limit: parseInt(limit),
          offset: (parseInt(page) - 1) * parseInt(limit),
          order: [['level', 'ASC'], ['createdAt', 'ASC']]
        });

        return {
          permissions: rows,
          pagination: {
            current: parseInt(page),
            total: Math.ceil(count / limit),
            pageSize: parseInt(limit),
            totalItems: count
          }
        };
      }
    } catch (error) {
      logger.error('Get permission list failed:', error);
      throw error;
    }
  }

  /**
   * 构建权限树
   */
  buildPermissionTree(permissions, parentId = null) {
    const tree = [];
    
    permissions.forEach(permission => {
      if (permission.parentId === parentId) {
        const children = this.buildPermissionTree(permissions, permission.id);
        if (children.length > 0) {
          permission.children = children;
        }
        tree.push(permission);
      }
    });

    return tree;
  }

  /**
   * 获取权限详情
   */
  async getPermissionById(permissionId) {
    try {
      const permission = await Permission.findByPk(permissionId, {
        include: [{
          model: Permission,
          as: 'parent'
        }, {
          model: Permission,
          as: 'children'
        }]
      });

      if (!permission) {
        throw new Error('权限不存在');
      }

      return permission;
    } catch (error) {
      logger.error('Get permission by id failed:', error);
      throw error;
    }
  }

  /**
   * 更新权限
   */
  async updatePermission(permissionId, updateData) {
    try {
      const permission = await Permission.findByPk(permissionId);
      
      if (!permission) {
        throw new Error('权限不存在');
      }

      // 系统权限不能修改
      if (permission.isSystem) {
        throw new Error('系统权限不能修改');
      }

      const { name, displayName, description, resource, action, category, status } = updateData;

      // 检查权限名是否已被其他权限使用
      if (name && name !== permission.name) {
        const existingPermission = await Permission.findOne({
          where: { 
            name,
            id: { [Op.ne]: permissionId }
          }
        });

        if (existingPermission) {
          throw new Error('权限名已存在');
        }
      }

      // 检查资源+操作组合是否已被其他权限使用
      if ((resource && resource !== permission.resource) || (action && action !== permission.action)) {
        const existingResourceAction = await Permission.findOne({
          where: { 
            resource: resource || permission.resource,
            action: action || permission.action,
            id: { [Op.ne]: permissionId }
          }
        });

        if (existingResourceAction) {
          throw new Error('该资源的操作权限已存在');
        }
      }

      await permission.update({
        name: name || permission.name,
        displayName: displayName || permission.displayName,
        description: description || permission.description,
        resource: resource || permission.resource,
        action: action || permission.action,
        category: category || permission.category,
        status: status || permission.status
      });

      return permission;
    } catch (error) {
      logger.error('Update permission failed:', error);
      throw error;
    }
  }

  /**
   * 删除权限
   */
  async deletePermission(permissionId) {
    try {
      const permission = await Permission.findByPk(permissionId);
      
      if (!permission) {
        throw new Error('权限不存在');
      }

      // 系统权限不能删除
      if (permission.isSystem) {
        throw new Error('系统权限不能删除');
      }

      // 检查是否有子权限
      const childCount = await Permission.count({
        where: { parentId: permissionId }
      });

      if (childCount > 0) {
        throw new Error('该权限下有子权限，不能删除');
      }

      // 检查是否有角色使用此权限
      const roleCount = await Role.count({
        include: [{
          model: Permission,
          as: 'permissions',
          where: { id: permissionId }
        }]
      });

      if (roleCount > 0) {
        throw new Error('该权限正在被使用，不能删除');
      }

      // 删除角色权限关联
      await RolePermission.destroy({
        where: { permissionId }
      });

      // 删除权限
      await permission.destroy();

      return true;
    } catch (error) {
      logger.error('Delete permission failed:', error);
      throw error;
    }
  }
}

module.exports = new RolePermissionService();